package server

import (
	"data_service/models"
	"fmt"
	"time"

	"gorm.io/gorm"
)

// AdminService 管理员服务
type AdminService struct {
	db *gorm.DB
}

// NewAdminService 创建管理员服务实例
func NewAdminService() *AdminService {
	db := models.GetDB()
	if db == nil {
		// 如果数据库未初始化，返回一个错误状态的服务
		return &AdminService{
			db: nil,
		}
	}
	return &AdminService{
		db: db,
	}
}

// NewAdminServiceWithDB 使用指定的数据库实例创建管理员服务
func NewAdminServiceWithDB(db *gorm.DB) *AdminService {
	return &AdminService{
		db: db,
	}
}

// ==================== 用户管理服务 ====================

// GetUserList 获取用户列表
func (s *AdminService) GetUserList(page, pageSize int, keyword, role, status string) ([]models.User, int64, error) {
	// 检查数据库连接
	if s.db == nil {
		return nil, 0, fmt.Errorf("数据库连接未初始化")
	}

	var users []models.User
	var total int64

	query := s.db.Model(&models.User{})

	// 添加搜索条件
	if keyword != "" {
		query = query.Where("name LIKE ? OR email LIKE ?", "%"+keyword+"%", "%"+keyword+"%")
	}
	if role != "" {
		query = query.Where("role = ?", role)
	}
	if status != "" {
		query = query.Where("status = ?", status)
	}

	// 获取总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 分页查询
	offset := (page - 1) * pageSize
	if err := query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&users).Error; err != nil {
		return nil, 0, err
	}

	return users, total, nil
}

// GetUserByID 根据用户ID获取用户信息
func (s *AdminService) GetUserByID(userID uint) (*models.User, error) {
	// 检查数据库连接
	if s.db == nil {
		return nil, fmt.Errorf("数据库连接未初始化")
	}

	var user models.User
	if err := s.db.Where("id = ?", userID).First(&user).Error; err != nil {
		return nil, err
	}
	return &user, nil
}

// UpdateUserRole 更新用户角色
func (s *AdminService) UpdateUserRole(userID uint, role string) error {
	// 检查数据库连接
	if s.db == nil {
		return fmt.Errorf("数据库连接未初始化")
	}

	// 验证角色（使用常量）
	if !models.IsValidRole(role) {
		return fmt.Errorf("invalid role: %s", role)
	}

	// 更新用户角色
	if err := s.db.Model(&models.User{}).Where("id = ?", userID).Update("role", role).Error; err != nil {
		return err
	}

	// 记录系统日志
	s.logSystemAction(userID, "update_role", "user", fmt.Sprintf("角色更新为: %s", role))

	return nil
}

// UpdateUserStatus 更新用户状态
func (s *AdminService) UpdateUserStatus(userID uint, status, reason string) error {
	// 验证状态（使用常量）
	if !models.IsValidStatus(status) {
		return fmt.Errorf("invalid status: %s", status)
	}

	// 更新用户状态
	if err := s.db.Model(&models.User{}).Where("id = ?", userID).Update("status", status).Error; err != nil {
		return err
	}

	// 记录系统日志
	action := "unban_user"
	if status == models.StatusBanned {
		action = "ban_user"
	}
	s.logSystemAction(userID, action, "user", fmt.Sprintf("状态更新为: %s, 原因: %s", status, reason))

	return nil
}

// GetUserStats 获取用户统计信息
func (s *AdminService) GetUserStats() (*models.UserStats, error) {
	// 检查数据库连接
	if s.db == nil {
		return nil, fmt.Errorf("数据库连接未初始化")
	}

	stats := &models.UserStats{}

	// 总用户数
	var totalUsers int64
	if err := s.db.Model(&models.User{}).Count(&totalUsers).Error; err != nil {
		return nil, err
	}
	stats.TotalUsers = int(totalUsers)

	// 活跃用户数（当前WebSocket连接的用户）
	var activeUsers int64
	if err := s.db.Model(&models.OnlineUser{}).Count(&activeUsers).Error; err != nil {
		// 如果OnlineUser表不存在或查询失败，使用最近1小时登录的用户作为活跃用户
		oneHourAgo := time.Now().Add(-1 * time.Hour)
		if err := s.db.Model(&models.User{}).Where("last_login > ?", oneHourAgo).Count(&activeUsers).Error; err != nil {
			return nil, err
		}
	}
	stats.ActiveUsers = int(activeUsers)

	// 管理员数量
	var adminUsers int64
	if err := s.db.Model(&models.User{}).Where("role = ?", models.RoleAdmin).Count(&adminUsers).Error; err != nil {
		return nil, err
	}
	stats.AdminUsers = int(adminUsers)

	// 被封禁用户数
	var bannedUsers int64
	if err := s.db.Model(&models.User{}).Where("status = ?", models.StatusBanned).Count(&bannedUsers).Error; err != nil {
		return nil, err
	}
	stats.BannedUsers = int(bannedUsers)

	// 今日新用户
	today := time.Now().Truncate(24 * time.Hour)
	var newUsersToday int64
	if err := s.db.Model(&models.User{}).Where("created_at >= ?", today).Count(&newUsersToday).Error; err != nil {
		return nil, err
	}
	stats.NewUsersToday = int(newUsersToday)

	return stats, nil
}

// ==================== 公告管理服务 ====================

// GetAnnouncementList 获取公告列表
func (s *AdminService) GetAnnouncementList(page, pageSize int, status, typeFilter string) ([]models.Announcement, int64, error) {
	// 检查数据库连接
	if s.db == nil {
		return nil, 0, fmt.Errorf("数据库连接未初始化")
	}

	var announcements []models.Announcement
	var total int64

	query := s.db.Model(&models.Announcement{})

	// 添加过滤条件
	if status != "" {
		query = query.Where("status = ?", status)
	}
	if typeFilter != "" {
		query = query.Where("type = ?", typeFilter)
	}

	// 获取总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 分页查询
	offset := (page - 1) * pageSize
	if err := query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&announcements).Error; err != nil {
		return nil, 0, err
	}

	return announcements, total, nil
}

// CreateAnnouncement 创建公告
func (s *AdminService) CreateAnnouncement(announcement *models.Announcement) error {
	if err := s.db.Create(announcement).Error; err != nil {
		return err
	}

	// 记录系统日志
	s.logSystemAction(announcement.AuthorID, "create_announcement", "announcement", fmt.Sprintf("创建公告: %s", announcement.Title))

	return nil
}

// PublishAnnouncement 发布公告
func (s *AdminService) PublishAnnouncement(announcementID uint) error {
	now := time.Now()
	if err := s.db.Model(&models.Announcement{}).Where("id = ?", announcementID).Updates(map[string]interface{}{
		"status":       "published",
		"publish_time": &now,
	}).Error; err != nil {
		return err
	}

	// 记录系统日志
	s.logSystemAction(0, "publish_announcement", "announcement", fmt.Sprintf("发布公告ID: %d", announcementID))

	return nil
}

// UpdateAnnouncement 更新公告
func (s *AdminService) UpdateAnnouncement(announcementID uint, updateData map[string]interface{}) error {
	if err := s.db.Model(&models.Announcement{}).Where("id = ?", announcementID).Updates(updateData).Error; err != nil {
		return err
	}

	// 记录系统日志
	s.logSystemAction(0, "update_announcement", "announcement", fmt.Sprintf("更新公告ID: %d", announcementID))

	return nil
}

// DeleteAnnouncement 删除公告
func (s *AdminService) DeleteAnnouncement(announcementID uint) error {
	if err := s.db.Delete(&models.Announcement{}, announcementID).Error; err != nil {
		return err
	}

	// 记录系统日志
	s.logSystemAction(0, "delete_announcement", "announcement", fmt.Sprintf("删除公告ID: %d", announcementID))

	return nil
}

// ==================== 系统管理服务 ====================

// GetSystemLogs 获取系统日志
func (s *AdminService) GetSystemLogs(page, pageSize int, action string, userID uint) ([]models.SystemLog, int64, error) {
	var logs []models.SystemLog
	var total int64

	query := s.db.Model(&models.SystemLog{})

	// 添加过滤条件
	if action != "" {
		query = query.Where("action = ?", action)
	}
	if userID > 0 {
		query = query.Where("user_id = ?", userID)
	}

	// 获取总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 分页查询
	offset := (page - 1) * pageSize
	if err := query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&logs).Error; err != nil {
		return nil, 0, err
	}

	return logs, total, nil
}

// GetSystemInfo 获取系统信息
func (s *AdminService) GetSystemInfo() (map[string]interface{}, error) {
	info := make(map[string]interface{})

	// 数据库信息
	var dbStats struct {
		UserCount         int64
		AnnouncementCount int64
		LogCount          int64
	}

	if err := s.db.Model(&models.User{}).Count(&dbStats.UserCount).Error; err != nil {
		return nil, err
	}
	if err := s.db.Model(&models.Announcement{}).Count(&dbStats.AnnouncementCount).Error; err != nil {
		return nil, err
	}
	if err := s.db.Model(&models.SystemLog{}).Count(&dbStats.LogCount).Error; err != nil {
		return nil, err
	}

	info["database"] = dbStats
	info["server_time"] = time.Now()
	info["timezone"] = "Asia/Shanghai"

	return info, nil
}

// ==================== 辅助方法 ====================

// logSystemAction 记录系统操作日志
func (s *AdminService) logSystemAction(userID uint, action, resource, details string) {
	log := &models.SystemLog{
		UserID:   userID,
		Action:   action,
		Resource: resource,
		Details:  details,
	}

	// 异步记录日志，避免影响主流程
	go func() {
		if err := s.db.Create(log).Error; err != nil {
			fmt.Printf("记录系统日志失败: %v\n", err)
		}
	}()
}
